import sys
parent_dir = "../pygl"
sys.path.append(parent_dir)
import ctypes
import OpenGL.GL as gl
import glm
import imgui
import numpy as np
import pygl
from common import App, Cube, AxesHelper, PerspectiveCamera, OrthographicCamera

class CameraApp(App):
    # 初始化着色器，vao vbo等
    def setupVertex(self) -> None:
        gl.glEnable(gl.GL_DEPTH_TEST)
        self.background_color = glm.vec4(0.3, 0.3, 0.3, 1.0)
        self.cube1 = Cube(1.0, "textures/cratetex.png")
        self.cube1.position = glm.vec3(2.0, 0.0, 0.0)
        self.cube2 = Cube(1.0)
        self.cube2.position = glm.vec3(2.0, 0.0, 5.0)
        self.cube3 = Cube(1.0)
        self.cube3.position = glm.vec3(2.0, 0.0, -5.0)
        self.cube4 = Cube(1.0, "textures/cratetex.png")
        self.cube4.position = glm.vec3(2.0, 0.0, -10.0)
        self.world_axes = AxesHelper(10.0, 2.0)
        self.imgui_window_width = 250
        self.imgui_window_height = 450

        # 保存ImGui的设置
        self.current_position = glm.vec3(0.0, 0.0, 10.0)
        self.current_target = glm.vec3(0.0, 0.0, 0.0)
        self.current_near = 1.0
        self.current_far = 21.0
        self.camera1 = PerspectiveCamera(90, float(self.width)/self.height, 
                self.current_near, self.current_far, self.current_position,
                self.current_target, glm.vec3(0.0, 1.0, 0.0))
        self.camera2 = OrthographicCamera(-5, 5, -5, 5, self.current_near, 
                self.current_far, self.current_position, self.current_target, 
                glm.vec3(0.0, 1.0, 0.0))
        self.selected_camera = 1
        self.current_camera = self.camera1

    # 配置imgui界面元素
    def showImGui(self)->None:
        # 增加ImGui窗口的透明度
        imgui_style = imgui.get_style()
        color = imgui_style.colors[imgui.COLOR_WINDOW_BACKGROUND]
        imgui_style.colors[imgui.COLOR_WINDOW_BACKGROUND] = imgui.Vec4(color.x, 
                                                    color.y, color.z, 0.6)
        imgui.begin("照相机设置")
        if imgui.button("重置"):
            self.current_position = glm.vec3(0.0, 0.0, 10.0)
            self.current_target = glm.vec3(0.0, 0.0, 0.0)
            self.current_near = 1.0
            self.current_far = 21.0
        if imgui.radio_button("透视投影", self.selected_camera == 1):
            self.selected_camera = 1
        if imgui.radio_button("正交投影", self.selected_camera == 2):
            self.selected_camera =2
        _, pos = imgui.slider_float3("位置", self.current_position.x, 
                    self.current_position.y, self.current_position.z, 0.0, 15.0)
        self.current_position = glm.vec3(pos)
        _, tg = imgui.slider_float3("目标", self.current_target.x, 
                        self.current_target.y, self.current_target.z, -1.0, 1.0)
        self.current_target = glm.vec3(tg)
        _, self.current_near = imgui.slider_float("近面", self.current_near,1.0, 10.0)
        _, self.current_far = imgui.slider_float("远面", self.current_far,10.0, 30.0)
        if self.selected_camera == 1:
            self.camera1.position = self.current_position
            self.camera1.center = self.current_target
            self.camera1.near = self.current_near
            self.camera1.far = self.current_far
            self.current_camera = self.camera1
        if self.selected_camera == 2:
            self.camera2.position = self.current_position
            self.camera2.center = self.current_target
            self.camera2.near = self.current_near
            self.camera2.far = self.current_far
            self.current_camera = self.camera2
        imgui.text("视图矩阵")
        imgui.begin_table("view data", 4)
        for i in range(4):
            imgui.table_next_row()
            for j in range(4):
                imgui.table_next_column()
                imgui.text(str("{:.3f}").format(self.view[j, i]))
        imgui.end_table()
        imgui.text("投影矩阵")
        imgui.begin_table("projection data", 4)
        for i in range(4):
            imgui.table_next_row()
            for j in range(4):
                imgui.table_next_column()
                imgui.text(str("{:.3f}").format(self.projection[j, i]))
        imgui.end_table()
        imgui.end()       

    # 渲染图形
    def render(self) -> None:
        gl.glClearBufferfv(gl.GL_COLOR, 0, self.background_color.to_tuple())
        gl.glClearBufferfv(gl.GL_DEPTH, 0, 1.0)
        self.view = self.current_camera.getViewMatrix()
        self.projection = self.current_camera.getProjectionMatrix()
        self.cube1.updateModelMatrix()
        self.cube1.render(self.view,self.projection)
        self.cube2.updateModelMatrix()
        self.cube2.render(self.view,self.projection)
        self.cube3.updateModelMatrix()
        self.cube3.render(self.view,self.projection)
        self.cube4.updateModelMatrix()
        self.cube4.render(self.view,self.projection)
        self.world_axes.updateModelMatrix()
        self.world_axes.render(self.view, self.projection)

    # 释放资源
    def cleanup(self) -> None:
        self.cube1.delete()
        self.cube2.delete()
        self.cube3.delete()
        self.cube4.delete()
        self.world_axes.delete()

if __name__ == "__main__":
    app = CameraApp(100, 100, 800, 800, "你好，照相机App V1.0！")
    app.run()

